package com.cljh.config.interceptor;

import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.cljh.bean.Admin;
import com.cljh.bean.User;
import com.cljh.config.AuthAccess;
import com.cljh.controller.page.Code;
import com.cljh.exception.SystemException;
import com.cljh.service.AdminService;
import com.cljh.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Jwt跨域 验证token
 */
//@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Autowired
    AdminService adminService;
    @Autowired
    UserService userService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {


        String token = request.getHeader("token");//获取前端发来的token

        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }else {
            HandlerMethod h= (HandlerMethod) handler;
            AuthAccess methodAnnotation = h.getMethodAnnotation(AuthAccess.class);
            if (methodAnnotation!=null){
                return true;
            }
        }

        //执行认证
        if (StrUtil.isBlank(token)) {
            throw new SystemException(Code.SYSTEM_ERR, "请先登录");
        }


        //获取token中的 id
        String username;
        try {
            username = JWT.decode(token).getAudience().get(0);
        } catch (JWTDecodeException e) {
            throw new SystemException(Code.SYSTEM_ERR, "token验证错误，请重新登录");
        }

        System.out.println(username);
        //根据token的username查询数据库
//        Admin admin = adminService.getById(Integer.valueOf(userId));

        Admin admin = new Admin();
        admin.setUsername(username);
        Admin admin1 = adminService.selectByUsername(admin);
        if (admin1 != null) {
            //验证token 用户密码加签验证
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(admin1.getPassword())).build();
            try {
                jwtVerifier.verify(token);//验证token
            } catch (JWTVerificationException e) {
                throw new SystemException(Code.SYSTEM_ERR, "密码错误，请重新登录");
            }
        }else {
            User user = userService.selectByUsername(username);
            if (user!=null){
                JWTVerifier jwtVerifier1 = JWT.require(Algorithm.HMAC256(user.getPwd())).build();
                try {
                    jwtVerifier1.verify(token);//验证token
                } catch (JWTVerificationException e) {
                    throw new SystemException(Code.SYSTEM_ERR, "密码错误，请重新登录");
                }
            } else {
                throw new SystemException(Code.SYSTEM_ERR, "用户不存在，请重新登录");
            }
        }
        //redis存储访问路径信息
        String uri = request.getRequestURI();
//        System.out.println(uri);
        stringRedisTemplate.opsForValue().increment(uri);
        stringRedisTemplate.opsForValue().increment("visit");
        return true;
    }
}
